package 面向对象.day06;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author 王敬仟
 * World 整个游戏
 */
public class World extends JPanel{
    //设置游戏窗口的宽 静态的不可改变的
    public static final int WIDTH=641;
    //设置游戏窗口的高 静态的不可改变的
    public static final int HEIGHT=479;
    //运行状态
    public static final int RUNNING = 0;
    //暂停状态
    public static final int PAUSE = 1;
    //游戏结束状态
    public static final int GAME_OVER = 2;
    //当前状态(默认为运行状态)
    private int state = RUNNING;
    //准备战舰
    private Battleship ship=new Battleship();
    //准备海洋对象数组
    private SeaObject[] submarines={};
    //准备鱼雷
    private Mine[] mines={};
    //准备炸弹
    private Bomb[] bombs={};
    //随机生成潜艇对象
    public SeaObject nextSeaObject(){
        Random rand=new Random();
        //定义海洋对象的总和
        int type=rand.nextInt(20);
        if(type<8){
            //生成鱼雷潜艇
            return new MineSubmarine();
        }else if (type<12){
            //生成侦查潜艇
            return new ObserverSubmarine();
        }else {
            //生成水雷潜艇
            return new TorpedoSubmarine();
        }
    }
    //设置初始时间为0
    private int subEnterIndex=0;
    //潜艇入场
    public void submarineEnterAction(){
        subEnterIndex++;
        //设置每400毫秒走一次
        if(subEnterIndex%40==0){
            //下一个对象
            SeaObject obj=nextSeaObject();
            //扩容
            submarines= Arrays.copyOf(submarines,submarines.length+1);
            //把新的对象加到数组中去
            submarines[submarines.length-1]=obj;
        }
    }
    //设置初始时间为0
    private int mineEnterIndex=0;
    //鱼雷 水雷入场
    public void mineEnterAction(){
        //每10毫秒增1
        ++mineEnterIndex;
        //每1000毫秒走一次
        if (mineEnterIndex%100==0){
            //遍历所有潜艇
            for(int i = 0; i < submarines.length; ++i) {
                //若潜艇为水雷潜艇
                if (submarines[i] instanceof MineSubmarine) {
                    //强转为水雷潜艇
                    MineSubmarine ms = (MineSubmarine)submarines[i];
                    //获取水雷对象
                    Mine obj = ms.shootMine();
                    //扩容
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    //把水雷放在最后一个元素上
                    mines[this.mines.length - 1] = obj;
                }
            }
        }
    }
    /*海洋对象移动*/
    public void moveAction(){
        //所有潜艇的移动
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].move();
        }
        //炸弹对象移动
        for(int i = 0; i < mines.length; ++i) {
            this.mines[i].move();
        }
        //鱼雷对象移动
        for(int i = 0; i < bombs.length; ++i) {
            bombs[i].move();
        }
    }
    /*删除越界的海洋对象*/
    public void outOfBoundsAction(){
        //便利海洋潜艇对象
        for(int i = 0; i < submarines.length; ++i) {
            //判断海洋对象是否越界
            if (submarines[i].isOutOfBounds() || submarines[i].isDead()) {
                //把元素放到最后一个
                submarines[i] = submarines[submarines.length - 1];
                //缩容
                submarines = Arrays.copyOf(submarines, submarines.length - 1);
            }
        }
        //便利所有的鱼雷
        for(int i = 0; i < mines.length; ++i) {
            //判断鱼雷是否越界
            if (mines[i].isOutOfBounds() || mines[i].isDead()) {
                //把元素放到最后一个
                mines[i] = mines[mines.length - 1];
                //缩容
                mines = Arrays.copyOf(mines, mines.length - 1);
            }
        }
        //便利所有的炸弹
        for(int i = 0; i < bombs.length; ++i) {
            //判断炸弹是否越界
            if (bombs[i].isOutOfBounds() || bombs[i].isDead()) {
                //把元素添加到最后一个
                bombs[i] = bombs[this.bombs.length - 1];
                //缩容
                bombs = Arrays.copyOf(bombs, bombs.length - 1);
            }
        }
    }
    /*海洋对象与战舰的碰撞 以及得分 加命 减命方案*/
    private int score = 0; //玩家得分
    //深水炸弹与潜艇的碰撞
    public void bombBangAction() {
        //遍历炸弹
        for (int i = 0; i < bombs.length; i++) {
            //每个炸弹等于数组中的元素
            Bomb b = bombs[i];
            //遍历海洋对象
            for (int j = 0; j < submarines.length; j++) {
                //所有的海洋对象等于数组中的元素
                SeaObject s = submarines[j];
                //判断是否是活着的还是死了的
                if (b.isLive() && s.isLive() && s.isHit(b)) {
                    //海洋对象去死
                    b.goDead();
                    //炸弹去死
                    s.goDead();
                    //判断得分
                    if (s instanceof EnemyScore) {//若被撞对象为得分对象
                        EnemyScore es = (EnemyScore) s;//强转为得分接口
                        score += es.getScore();//战舰增分
                    }
                    //判断战舰得分
                    if (s instanceof EnemyLife) {
                        EnemyLife ea = (EnemyLife) s;//被撞对象强转为得命接口
                        int life = ea.getLife();//获取命数
                        ship.addLife(life);//战舰增命
                    }
                }
            }
        }
    }
    //水雷与战舰的碰撞
    public void mineBangAction() {
        //遍历所有的水雷
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            //若都活着而且还撞上了
            if (m.isLive() && ship.isLive() && m.isHit(ship)) {
                m.goDead();//水雷去死
                ship.subtractLife();//战舰减命
            }
        }
    }
    //检测游戏结束
    public void checkGameOverAction(){
        if(ship.getLife()<=0){//若战舰的命<=0则表示战舰结束了
           state=GAME_OVER;//将当前状态修改为游戏结束状态
        }
    }
    /** 启动程序的运行 */
    public void action(){
        KeyAdapter k= new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                //VK_ENTER若抬起的键是回车键则暂停
                if(e.getKeyCode() == KeyEvent.VK_ENTER){
                    //判断当前状态是否是运行状态
                    if (state==RUNNING){
                        //是运行状态则则暂停
                        state=PAUSE;
                        //是暂停状态
                    }else if (state==PAUSE){
                        //则运行
                        state=RUNNING;
                    }
                }
                //只在运行状态时执行
                if (state==RUNNING) {
                    if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                        //深水炸弹入场
                        Bomb obj = ship.shootbomb();
                        //扩容
                        bombs = Arrays.copyOf(bombs, bombs.length + 1);
                        //把炸弹放在最后一个元素上
                        bombs[bombs.length - 1] = obj;
                    }
                    //判断VK_LEFT左键移动
                    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        ship.moveLeft();
                    }
                    //判断右键移动
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        ship.moveRight();
                    }
                }
            }
        };
        this.addKeyListener(k);
        Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            public void run() {
                //仅在运行状态时执行
                if (state==RUNNING) {
                    submarineEnterAction(); //(侦查潜艇,鱼雷潜艇,水雷潜艇)入场
                    mineEnterAction();//(鱼雷,水雷)入场
                    moveAction();//海洋对象的移动
                    outOfBoundsAction();//删除越界的海洋对象
                    bombBangAction();//炸弹也战舰的碰撞
                    mineBangAction();//水雷与战舰的碰撞
                    checkGameOverAction();//游戏结束
                    repaint();//重画对象
                }
            }
        }, interval, interval);
    }
    //往游戏窗口中画对象
    public void paint(Graphics g){
        //画海洋图
        Iamges.sea.paintIcon(null,g,0,0);
        //跟中海洋图 并画出海洋图
        ship.paintImage(g);
        //便利海洋潜艇对象
        for (int i=0;i<submarines.length; ++i){
            //画潜艇对象
            submarines[i].paintImage(g);
        }
        //便利所有的炸弹
        for (int i = 0; i < this.bombs.length; ++i){
            //画炸弹
            bombs[i].paintImage(g);
        }
        //便利所有的鱼雷
        for (int i = 0; i < mines.length; ++i){
            //画鱼雷
            mines[i].paintImage(g);
        }
        //初始分数 x y 指的是显示的位置
        g.drawString("SCORE: "+score,200,50);
        //初始命数 x y 指的是显示的位置
        g.drawString("LIFE: "+ship.getLife(),400,50);
        //判断当前状态是否是游戏结束状态  2->游戏结束显示图
        if (state ==GAME_OVER) {
            //则显示游戏结束图片
            Iamges.gameover.paintIcon((Component)null, g, 0, 0);
        }
    }
    //画窗口
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16, HEIGHT+39);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        world.action();
    }
}
